package com.yycx.module.pay.provider.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.egzosn.pay.ali.bean.AliTransferType;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.TransferOrder;
import com.egzosn.pay.wx.bean.WxTransferType;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.enums.StateEnum;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.utils.ApiAssert;
import com.yycx.common.utils.DateUtils;
import com.yycx.module.pay.client.entity.PayBalanceLog;
import com.yycx.module.pay.client.entity.PayCashout;
import com.yycx.module.pay.client.entity.PayConfig;
import com.yycx.module.pay.client.enums.PayType;
import com.yycx.module.pay.provider.mapper.PayConfigMapper;
import com.yycx.module.pay.provider.response.PayResponse;
import com.yycx.module.pay.provider.service.PayBalanceLogService;
import com.yycx.module.pay.provider.service.PayBalanceService;
import com.yycx.module.pay.provider.service.PayCashoutService;
import com.yycx.module.pay.provider.service.PayConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 支付账户配置 实现类
 *
 * @author flyme
 * @date 2019-06-22
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PayConfigServiceImpl extends BaseServiceImpl<PayConfigMapper, PayConfig> implements PayConfigService {
    @Autowired
    private PayCashoutService cashoutService;
    @Autowired
    private PayBalanceService balanceService;
    @Autowired
    private PayBalanceLogService balanceLogService;
    /**
     * 缓存
     */
    private final static Map<String, PayResponse> payResponses = new HashMap();


    /**
     * 获取支付响应
     *
     * @param payConfigId 支付配置id
     * @return 支付响应
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public PayResponse getPayResponse(String outTradeNo,Long payConfigId, String handlerName) {
        PayResponse payResponse = new PayResponse();
        PayConfig payConfig = getById(payConfigId);
        ApiAssert.isNotEmpty("支付配置不存在", payConfig);
        spring.autowireBean(payResponse);
        payConfig.setOutTradeNo(outTradeNo);
        payResponse.init(payConfig, handlerName);
        return payResponse;
    }


    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody beforeListEntityMap(CriteriaQuery<PayConfig> cq, PayConfig payConfig, EntityMap requestMap) {
        cq.select(entityClass, "payId", "payLogo", "payName", "appId", "payCode","transactionType","payDesc");
        cq.eq(true, "payStatus", StateEnum.ENABLE.getCode());
        return super.beforeListEntityMap(cq, payConfig, requestMap);
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public List<EntityMap> selectPayTypes() {
        CriteriaQuery cq = new CriteriaQuery(PayConfig.class);
        cq.select(PayConfig.class, "payId", "payName", "payLogo");
        cq.eq(true, "payStatus", StateEnum.ENABLE.getCode());
        return baseMapper.selectEntityMap(cq);
    }


    @Override
    public ResultBody setPayStatus(Long[] ids, Integer payStatus) {
        ApiAssert.isNotEmpty("主键不能为空", ids);
        UpdateWrapper product = new UpdateWrapper();
        product.set("payStatus", payStatus);
        product.in("payId", ids);
        boolean result = update(product);
        if (result) {
            return ResultBody.ok("操作成功", payStatus);
        } else {
            return ResultBody.failed("操作失败");
        }
    }


    @Override
    public ResultBody setIsTest(Long[] ids, Integer isTest) {
        ApiAssert.isNotEmpty("主键不能为空", ids);
        UpdateWrapper product = new UpdateWrapper();
        product.set("isTest", isTest);
        product.in("payId", ids);
        boolean result = update(product);
        if (result) {
            return ResultBody.ok("操作成功", isTest);
        } else {
            return ResultBody.failed("操作失败");
        }
    }

    @Override
    public ResultBody doCashout(Long cashoutId, Integer balanceLogType, String handlerName) {
        ApiAssert.allNotNull("参数不正确", cashoutId, balanceLogType);
        PayCashout cashout = cashoutService.getById(cashoutId);//提现申请记录
        ApiAssert.isNotEmpty("提现记录不存在", cashout);
        //如果提现申请的状态不是0提示已经提现成功（提现申请的状态：-1提现失败 0审核中 1提现成功）
        ApiAssert.eq("已经提现成功，请勿重复操作", cashout.getStatus(), 1);
        PayBalanceLog balanceLog = balanceLogService.findByBusIdAndType(cashoutId, balanceLogType);//余额记录
        ApiAssert.isNotEmpty("余额记录不存在", balanceLog);
        //如果余额记录的状态不是0提示已经提现成功 （余额记录的状态：-1提现失败 0审核中 1提现成功）
        if (balanceLog.getStatus() == 1) {
            ApiAssert.failure("已经提现成功，请勿重复操作");
        }
        Long payId = cashout.getPayId();
        PayResponse payResponse = getPayResponse(null,payId, handlerName);//初始化支付方式
        PayService service = payResponse.getService();
        TransferOrder transferOrder = new TransferOrder();
        if (cashout.getCashoutType().equals(PayType.aliPay.name())) {
            transferOrder.setOutNo(cashoutId + "");//转账单号
            transferOrder.setPayeeAccount(cashout.getAliPayAccount());//收款方账户,支付宝登录号，支持邮箱和手机号格式
            transferOrder.setAmount(cashout.getRealMoney());//转账金额
            //transferOrder.setPayerName("付款方姓名, 非必填");//付款方姓名, 非必填
            //transferOrder.setPayeeName("收款方真实姓名, 非必填");
            //transferOrder.setRemark("转账备注, 非必填");//转账备注, 非必填
            //收款方账户类型 ,默认值 ALIPAY_LOGONID：支付宝登录号，支持邮箱和手机号格式。
            //TODO 版本升级更改
            transferOrder.setTransferType(AliTransferType.STD_RED_PACKET);
        } else {
            transferOrder.setOutNo(cashoutId + "");//partner_trade_no 商户转账订单号
            transferOrder.setPayeeAccount(cashout.getWxOpenId());//用户openId
            //transferOrder.setPayeeName("收款用户姓名， 非必填，如果填写将强制验证收款人姓名");
            transferOrder.setRemark("提现");
            transferOrder.setAmount(cashout.getRealMoney());
            //转账到余额，这里默认值是转账到银行卡
            transferOrder.setTransferType(WxTransferType.TRANSFERS);
        }
        Map<String, Object> map = service.transfer(transferOrder);
        if (PayType.aliPay.name().equals(cashout.getCashoutType())) {
            JSONObject object = (JSONObject) map.get("alipay_fund_trans_toaccount_transfer_response");
            Map result = object.toJavaObject(Map.class);
            System.out.println("code:" + result.get("code"));
            String code = (String) result.get("code");
            if ("10000".equals(code)) {
                //更新余额 TODO
                cashout.setStatus(1);//更新提现状态为提现成功  -1提现失败 0审核中 1提现成功
                cashout.setArriveTime(DateUtils.getNowDateTime());
                balanceLog.setStatus(1);//更新余额记录状态为提现成功  -1提现失败 0审核中 1提现成功
            } else {
                //更新余额 TODO
                //这里不做更新，如果有错误返回，后台管理手动填写提现失败原因，再做提现失败的操作
                ApiAssert.failure((String) result.get("sub_msg"));
            }
        }
        if (PayType.wxPay.name().equals(cashout.getCashoutType())) {
            String code = (String) map.get("result_code");
            if ("SUCCESS".equals(code)) {
                //转账成功，更新余额
                //更新提现状态为提现成功  -1提现失败 0审核中 1提现成功
                cashout.setStatus(1);
                cashout.setArriveTime(DateUtils.getNowDateTime());
                //更新余额记录状态为提现成功  -1提现失败 0审核中 1提现成功
                balanceLog.setStatus(1);
            } else {
                //更新余额 TODO
                //这里不做更新，如果有错误返回，后台管理手动填写提现失败原因，再做提现失败的操作
                ApiAssert.failure((String) map.get("return_msg"));
            }
        }
        balanceLog.updateById();
        cashout.updateById();
        return ResultBody.msg("转账成功");
    }


}
